المجموعات

فايلات الفولدر
columns.tsx;
GroupsRequest.ts;
useGroups.ts;
GroupsView.tsx;
columns.tsx
export const getColumns = (t: TFunction): ColumnDef<Group>[] => {
return [
{
accessorKey: "id",
header: t("id"),
size: 10,
meta: {
align: "center",
},
},
{
accessorKey: "imageLink",
size: 120,
header: t("image"),
cell: ({ row }) => {
const imagePath = row.getValue("imageLink") as string;
return (
<>
{imagePath ? (
<img
src={`${imageUrl}${imagePath}`}
alt="item"
className="w-16 h-16 rounded-full border border-secondary"
/>
) : (
<div className="w-16 h-16 rounded-full border flex justify-center items-center border-secondary">
<ImageOff />
</div>
)}
</>
);
},
},
{
accessorKey: "name",
header: t("name"),
size: 180,
},
{
accessorKey: "parentGroupName",
header: t("pages.products.Groups.parentGroup"),
size: 180,
},
];
};
-
هاي الدالة مسؤولة عن توليد الأعمدة إلي راح تنعرض بجدول المجاميع
-
accessorKey: يحدد شنو المفتاح داخل كل صف من البيانات حتى يتم عرضه. -
header: العنوان المعروض بأعلى العمود، ومترجم حسب اللغة. -
cell: إذا تريد تتحكم شلون تنعرض البيانات، مثل ما سوينا بالصورة. -
size: يحدد عرض العمود بالجدول. -
meta: معلومات إضافية للعرض (مثل اخلي النص بالنص).
GroupsRequest.ts
import * as z from "zod";
export const schema = z.object({
name: z.string({ required_error: "يجب ادخال اسم المجموعة" }),
parentGroupId: z.number().nullable().optional(),
imageLink: z.union([
z.string().optional(),
z.instanceof(File, { message: "نوع الصورة خطأ" }).optional(),
]),
});
export type GroupsRequest = z.infer<typeof schema>;
- هنانة هاي السكيما مال الفورمة مالتنة ويا ال Validation مالتها يعني راح يكعد يتأكد شنو حيكون اختياري وشنو اجباري ونوع البيانات مالتها شنو ويرجع رسالة في حال خال الشروط مال المتغير المعين
useGroups.ts
export const useGetInfinteScrollGroupsQuery = (query: string, sort: string) => {
return useInfiniteQuery<Group[]>({
queryKey: ["groups", query, sort],
queryFn: async ({ pageParam = 0 }) => {
const fetchSize = 10;
const offset = (pageParam as number) * fetchSize;
const fetchedData = await getInfinteScrollGroups(
offset,
fetchSize,
query,
sort
); //pretend api call
return fetchedData;
},
initialPageParam: 0,
getNextPageParam: (lastPage, allPages) => {
const nextOffset = lastPage.length ? allPages.length : undefined;
return nextOffset;
},
});
};
-
هاي الدالة شغلها راح تجيب البيانات مال المجاميع بشكل دفعات يعني راح يضل يجيب 10 كل ما المستخدم يسوي Scroll بالصفحة
-
(
/groups?offset=${offset}&limit=${fetchSize}&search=${query}&sort=${sort});-
query: هاي البحث مالتي يعني اني شنو كتبت بالانبوت مال البحث من قيمة راح ينحط هنا -
sort: هاي هنا الفرز مالتك تصاعدي لو تنازلي حيكون -
fetchSize: شكد عدد الصفوف الي تريد تجيبها (بهذا المثال هي عشرة ) -
offset: هو العدد الي راح نبدي نجيب من عندة البيانات مالتنة او الاسطر يعني اني جبت الدفعة الاولى وجانت 10 بعدين حبدي اجيب من 11 الحد 20 و وهنا ال offset مالتي بدة من نهاية الدفعة القبلها الي هي العشرةمثال على الاوف سيتالدفعة offset معناها الأولى 0 جيبلي أول 10 عناصر (من 0 إلى 9) الثانية 10 جيبلي من العنصر 11 إلى 20 الثالثة 20 جيبلي من العنصر 21 إلى 30 الرابعة 30 وهكذا...
-
-
getNextPageParam: هاي راح تشوف اذا اكو بعد بيانات نجيبها لو لا حتى نسوي صفحة لخ واذا لا فراح توكف ومراح تطلب بعد بيانات يعنيإذا أكو بيانات بالصفحة الأخيرة => نكمل ونحسب offset الجاي
إذا ماكو => نوكف جلب البيانات
const createGroupMutation = useMutation({
mutationFn: createGroup,
onSuccess: () => {
queryClient.invalidateQueries({
queryKey: ["groups"],
});
setOpenDialog(false);
setSelectedGroup(null);
reset(defaultValues);
setImagePreview(null);
},
});
//---------------------------------//
const editGroupMutation = useMutation({
mutationFn: editGroup,
onSuccess: () => {
queryClient.invalidateQueries({
queryKey: ["groups"],
});
setOpenDialog(false);
setSelectedGroup(null);
reset(defaultValues);
setImagePreview(null);
},
});
//---------------------------------//
const removeGroupMutation = useMutation({
mutationFn: removeGroup,
onSuccess: () => {
queryClient.invalidateQueries({
queryKey: ["groups"],
});
setOpenDialog(false);
setSelectedGroup(null);
reset(defaultValues);
setImagePreview(null);
},
});
- هذني الدوال راح تسوي عملية حذف , اضافة , تحديث للمجاميع وطبعا ورة ما يصير نجاح بالعملية مجموعة من المتغيرات راح تصفر والي هي كدامك
- ايضا راح يصير عملية Refetch للبيانات مالتك بالصفحة لان صار تحديث على الكاش القديم لهذا راح يسوي Refetch علمود يخزن النتيجة الجديدة بالكاش
const openAddDialog = () => {
setOpenDialog(true);
setSelectedGroup(null);
reset(defaultValues);
setImagePreview(null);
};
//---------------------------------//
const openEditDialog = (id: number) => {
const group = infinteScrollGroups?.pages
.flatMap((d) => d)
?.find((grp) => grp.id == id);
if (group) {
setSelectedGroup(id);
setOpenDialog(true);
setImagePreview(
group.imageLink && typeof group.imageLink === "string"
? `${imageUrl}${group.imageLink}`
: null
);
reset({
name: group.name,
imageLink: group.imageLink,
parentGroupId: group.parentGroupId,
});
}
};
//---------------------------------//
const openDeleteDialog = (id: number) => {
const group = infinteScrollGroups?.pages
.flatMap((d) => d)
?.find((grp) => grp.id == id);
if (group) {
setDeleteDialog(true);
setSelectedGroup(id);
}
};
openAddDialog: هنا راح تفتح النافذة مال اضافة مجموعة جديدة وراح يصفر البيانات القديمة في حال جانت اكو بياناتopenEditDialog: اول شي راح يسوي Flatting لل Array بعدين راح يجيك هل المجموعة موجودة لو لا وراح يحط القيم اذا موجودة لو لاopenDeleteDialog: راح يسوي Flat to the List وراح يجيك اذا الكروب موجود لو لا وبعدين راح يفتح النافذة مال الحذف مالتك
const onSubmit = (data: GroupsRequest) => {
if (selectedGroup) {
editGroupMutation.mutate({ id: selectedGroup, data: data });
} else {
createGroupMutation.mutate(data);
}
};
- اذا اكو كروب فراح يسوي عملية تحديث واذا لا راح يسوي اضافة
GroupsView.tsx
const { t, i18n } = useTranslation();
const columns = useMemo(() => getColumns(t), [t, i18n.language]);
useTitle(t("pages.products.Groups.title"));
const { updateBreadcrumbs } = useBreadcrumbs();
useEffect(() => {
updateBreadcrumbs([
{ label: t("pages.products.Groups.title"), link: "/groups" },
]);
}, [i18n.language]);
- هنا تم استدعاء الدوال الخاصة بعملية ترجمة من لغة الى لغة لخ وهمينة جبنة الاعمدة باستخدام ال useMemeo وخليناه يسوي رندرة من تتغيرة اللغة مالتنة
- ايضا حطينة التايتل مال الصفحة بال Breadcrumbs
- باقي الصفحة هو عبارة عن عرض البيانات وبيه مجموعة من ال Sharded Components الي راح يتم شرحها بالملفات المشتركة